package us.codecraft.webmagic.processor.example;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import com.alibaba.fastjson.JSONObject;

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.pipeline.ResultItemsCollectorPipeline;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.utils.HttpConstant;

public class HotelGGPagePostProcessor implements PageProcessor {

	private static final String searchKeyWord ="iiiitwmwjwrwuwf";  
	private static final Integer pageNum = 110;
	private static final String LoginPage = "https://www.hotelgg.com/login";
	private static final String PAGE = "https://www.hotelgg.com/venue/m" + searchKeyWord;
	private static final String saveFileUrl ="d:\\webmagic\\hotelgg.csv";
	// 部分一：抓取网站的相关配置，包括编码、抓取间隔、重试次数等
	private Site site = Site.me().setRetryTimes(5).setSleepTime(1000).setTimeOut(10000)
			.setDomain("www.hotelgg.com")
            .addHeader("Accept", "application/json, text/javascript, */*; q=0.01")  
            .addHeader("Accept-Encoding", "gzip, deflate, sdch")
            .addHeader("Accept-Language", "en-US,en;q=0.8,zh-CN;q=0.6")  
            .addHeader("Connection", "keep-alive")
            .addHeader("X-Requested-With", "XMLHttpRequest")
            .addHeader("User-Agent",  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36") ; 

	
	public static void main(String[] args) {
		
		System.setProperty("http.proxySet", "true"); 
		System.setProperty("http.proxyHost", "127.0.0.1"); 
		System.setProperty("http.proxyPort", "8888");
		
		initializePageUrl(pageNum);
		
		//设置POST请求
		Request request = new Request(LoginPage);
		//只有POST请求才可以添加附加参数
		request.setMethod(HttpConstant.Method.POST);

		//设置POST参数
		List<NameValuePair> nvs = new ArrayList<NameValuePair>();
		nvs.add(new BasicNameValuePair("type", "account"));
		nvs.add(new BasicNameValuePair("account", "13918940140"));
		nvs.add(new BasicNameValuePair("password", "123456"));
		nvs.add(new BasicNameValuePair("captcha", ""));
		
		//转换为键值对数组
		NameValuePair[] values =  nvs.toArray(new NameValuePair[4]);

		//将键值对数组添加到map中
		Map<String, Object> params = new HashMap<String, Object>();
		//key必须是：nameValuePair
		params.put("nameValuePair", values);

		//设置request参数
		request.setExtras(params);
		
		ResultItemsCollectorPipeline pipeline =new ResultItemsCollectorPipeline();
		Spider spider = Spider.create(new HotelGGPagePostProcessor());
				// 开始抓取的页面
		spider.addRequest(request);
				// 开启5个线程抓取
		spider.thread(1);
				// 启动爬虫
		spider.run();
		//保存到表格
		saveExcel(pipeline);
	}
	
	private static void saveExcel(ResultItemsCollectorPipeline pipeline){
		 // 第一步，创建一个workbook对应一个excel文件
 		HSSFWorkbook workbook = new HSSFWorkbook();
 		// 第二部，在workbook中创建一个sheet对应excel中的sheet
 		HSSFSheet sheet = workbook.createSheet("酒店哥哥会厅全套价格");
 		// 第三部，在sheet表中添加表头第0行，老版本的poi对sheet的行列有限制
 		HSSFRow row = sheet.createRow(0);
 		// 第四步，创建单元格，设置表头
 		HSSFCell cell = row.createCell(0);
 		cell.setCellValue("hotelggId");
 		cell = row.createCell(1);
 		cell.setCellValue("hotelName");
 		cell = row.createCell(2);
 		cell.setCellValue("meetingGGID");
 		cell = row.createCell(3);
 		cell.setCellValue("meetingName");
 		cell = row.createCell(4);
 		cell.setCellValue("alldayPrice");
 		cell = row.createCell(5);
 		cell.setCellValue("halfPrice");

 		// 第五步，写入实体数据
        List<ResultItems> resultItemsList = pipeline.getCollected();
        int index = 1;
        for (ResultItems item : resultItemsList) {
 			if (item.get("hotel")!=null) {
     			HotelInfo hotel = (HotelInfo)item.get("hotel");
     			for (MeetingInfo meeting : hotel.meetingInfos) {
         			HSSFRow row1 = sheet.createRow(index++); 
         			// 创建单元格设值
         			row1.createCell(0).setCellValue(hotel.getHotelggId());
         			row1.createCell(1).setCellValue(hotel.getHotelName());
         			row1.createCell(2).setCellValue(meeting.getMeetingGGID());
         			row1.createCell(3).setCellValue(meeting.getMeetingName());
         			row1.createCell(4).setCellValue(meeting.getAlldayPrice());
         			row1.createCell(5).setCellValue(meeting.getHalfPrice());
				}
			}
        }

 		// 将文件保存到指定的位置
 		try {
 			FileOutputStream fos = new FileOutputStream(saveFileUrl);
 			workbook.write(fos);
 			System.out.println("写入成功");
 			fos.close();
 			workbook.close();
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
	}
	
	private static Map<Integer, String> mapPageUrl = new HashMap<Integer, String>();

	/*
	 * 酒店哥哥有数字加密，这里做下转义并直接生成分页地址
	 */
	private static void initializePageUrl(Integer pageNum) {
		Map<Integer, String> num2Word = new HashMap<Integer, String>();//乱码对照数字表
		num2Word.put(0, "l");
		num2Word.put(1, "m");
		num2Word.put(2, "j");
		num2Word.put(3, "o");
		num2Word.put(4, "f");
		num2Word.put(5, "r");
		num2Word.put(6, "s");
		num2Word.put(7, "t");
		num2Word.put(8, "u");
		num2Word.put(9, "v");
		for (Integer i = 1; i < pageNum; i++) {
			Integer size = i.toString().length();
			String pageIndex = "";
			for (Integer j = 0; j < size; j++) {
				pageIndex += num2Word.get(Integer.valueOf(i.toString().substring(j, j + 1)));
			}
			pageIndex = "https://www.hotelgg.com/venue/" + pageIndex + searchKeyWord;
			mapPageUrl.put(i, pageIndex);
		}
	}

	private static Integer pageIndex = 2;// 记录分页游标

	@Override
	public void process(Page page) {
		if(page.getUrl().get().equals("https://www.hotelgg.com/login")){
			List<String> listPage = new ArrayList<String>();
			listPage.add(PAGE);
			//page.addTargetRequests(listPage);
		}
//		else if (page.getUrl().get().contains(searchKeyWord)) {
//			System.out.println("列表页获取内容页链接******************************");
//			List<String> urls = page.getHtml().css("h3.title").links().all();
//			if (urls.size() > 0) {
//				urls.add(mapPageUrl.get(pageIndex++));// 有内容就继续翻页
//			}
//			page.addTargetRequests(urls);
//		} else if(page.getUrl().get().contains("https://www.hotelgg.com/view-")) {
//			System.out.println("内容页获取酒店信息及meetingid----------------------------------");
//			initialHotelInfo(page);
//		}
//		else if(page.getUrl().get().contains("https://www.hotelgg.com/meetingroom/alldayprice/")) {
//			System.out.println("会厅价格----------------------------------");
//			setmeetingPrice(page);
//		}
	}

	private void setmeetingPrice(Page page) {
	    HotelInfo hotel =	hotels.get(page.getUrl().toString());
	    String originJson =  page.getHtml().toString().replace("<html>", "").replace("<head>", "").replace("</head>", "").replace("<body>", "").replace("</html>", "").replace("</body>", "").replace("\n", "").replace("\\uffe5", "");
	    JSONObject jsonData = JSONObject.parseObject(originJson).getJSONObject("data");
	    for (MeetingInfo room : hotel.getMeetingInfos()) {
	    	room.alldayPrice = ((JSONObject)jsonData.get( room.getMeetingGGID())).get("allday_price").toString();
	    	room.halfPrice = ((JSONObject)jsonData.get( room.getMeetingGGID())).get("halfday_price").toString();
		}
	    page.putField("hotel", hotel);
	}

	public static Map<String, HotelInfo> hotels = new HashMap<String, HotelInfo>();
	
	/*
	 * 初始化构建酒店信息基础 Map<PriceUrl,HotelInfo>
	 */
	private void initialHotelInfo(Page page) {
		HotelInfo hotel = new HotelInfo();
		// 1、获取酒店内容页中酒店级信息，如id，name , star等
		hotel.hotelggId =page.getUrl().all().get(0).replaceAll("\\D", "");
		List<String> hotelName = page.getHtml().css("div.bread-crumbs").css("span", "text").all();
		hotel.hotelName = hotelName.isEmpty() ? "" : hotelName.get(0);

		// 2、实例会厅信息,  取酒店相关会厅价格数据页地址
		List<String> meetingNames = page.getHtml().css("div.mt_name").css("strong","text").all();
		List<MeetingInfo> meetings = new ArrayList<MeetingInfo>();
		List<String> urls = page.getHtml().css("a.view_price_meetingroom", "data-meetingroom-id").all();
		StringBuilder getMeetingPriceUrl = new StringBuilder("https://www.hotelgg.com/meetingroom/alldayprice/");
		for (int i = 0; i < urls.size(); i++) {
			MeetingInfo meeting = new MeetingInfo();
			meeting.meetingGGID = urls.get(i);
			getMeetingPriceUrl.append(urls.get(i)).append((i < urls.size() - 1) ? "," : "");
			meeting.meetingName = meetingNames.get(i);
			meetings.add(meeting);
		}
		page.addTargetRequest(getMeetingPriceUrl.toString());
		hotel.meetingInfos = new ArrayList<MeetingInfo>();
		hotel.meetingInfos.addAll(meetings);
		
		//3、getmeetingPriceUrl用做字典的key值，方便获取价格后快速查找对应酒店对象。
		hotels.put(getMeetingPriceUrl.toString(),hotel);;
	}

	@Override
	public Site getSite() {
		return site;
	}
}
